<template>
  <div
    class="file_edit"
    v-if="rendering"
  >
    <div class="file_edit_top">
      <TopBox :title="fileName">
        <FilterSearch
          :placeholder="'请输入文档名称'"
          :searchCallBack="searchCallBack"
        />
        <!-- <topButtonGroup :buttonList="tbuttonList" /> -->
        <topButtonGroupDoc :buttonList="tbuttonList" />
      </TopBox>
    </div>
    <div class="file_edit_cotent">
      <div
        class="tree_box"
        :style="{ width: `${leftWidth}%` }"
        v-show="isCatalogShow"
      >
        <div class="but_box">
          <el-button
            icon="Plus"
            type="primary"
            size="small"
            @click="updataOutline('add', true)"
          >添加</el-button>
          <el-button
            size="small"
            icon="Sort"
            @click="onExpand"
          >{{ isExpand ? '折叠' : '展开' }}</el-button>
        </div>
        <el-tree
          ref="treeRef"
          :data="treeData"
          :props="defaultProps"
          node-key="id"
          draggable
          :allow-drop="allowDrop"
          :allow-drag="allowDrag"
          @node-drop="nodeDrop"
          default-expand-all
          @node-click="handleNodeClick"
          :expand-on-click-node="false"
        >
          <template #default="{ node, data }">
            <div
              class="custom-tree-node"
              @contextmenu.prevent="treeHandleRightClick($event, data)"
            >
            <span>
                <el-icon>
                  <Edit />
                </el-icon>
                {{ node.label }}
              </span>
              <!-- <div
                class="_contextmenu"
                @contextmenu.prevent="treeHandleRightClick($event, data)"
              >
              </div> -->
            </div>
          </template>
        </el-tree>
      </div>
      <div
        class="divider"
        @mousedown="startDrag"
      ></div>
      <jodit
        v-if="fileName"
        @catalogShow='catalogShow'
        :treeDataMap="treeDataMap"
        :htmlStructure='htmlStructure'
      />
    </div>
    <!-- 内容区域复制的dom -->
    <!-- <div
      id="jodit_copy"
      v-html="htmlStructure"
    ></div> -->
    <!-- 自定义菜单 -->
    <input
      ref="menuInputRef"
      @blur="handleBlur"
      @focus="handleFocus"
      class="menuInput"
    />
    <div
      v-if="showMenu"
      class="context_menu"
      :style="menuStyle"
    >
      <ul>
        <li
          @click.stop="updataOutline('add')"
          v-if="currentNode.level <= 2"
        >添加</li>
        <li @click.stop="updataOutline('updata')">修改</li>
        <li @click.stop="deleteOutline">删除</li>
      </ul>
    </div>

    <!-- 文档详情弹窗 -->
    <el-dialog
      v-model="fileDetailsDialog"
      title="文档信息"
      width="400px"
      align-center
      modal-class="file_details_dialog"
      @close="fileDetailsDialog = false"
    >
      <div class="file_details_box">
        <div class="_line"></div>
        <div class="details">
          <h2>软件开发计划</h2>
          <div class="_box">
            <p>创建者: Admin</p>
            <p>创建时间: 2025/2/10 星期一 10:10</p>
            <p>最近更新: 2025/2/10 星期一 10:10</p>
          </div>
        </div>
        <div class="_tabs">
          <el-tabs v-model="tabsActiveName">
            <el-tab-pane
              name="version"
              label="版本信息"
            >版本信息</el-tab-pane>
            <el-tab-pane
              name="process"
              label="流程信息"
            >流程信息</el-tab-pane>
            <el-tab-pane
              name="comment"
              label="评论信息"
            >评论信息</el-tab-pane>
          </el-tabs>
        </div>
        <!-- <div class="_line"></div> -->
      </div>
      <!-- <template #footer>
        <div class="dialog_footer">
          <el-button
            :disabled="countdown !== 0"
            @click="submitMemberListAction(false)"
          >否{{ countdown ? `(${countdown})` : "" }}</el-button>
          <el-button
            type="primary"
            :disabled="countdown !== 0"
            @click="submitMemberListAction(true)"
          >是{{ countdown ? `(${countdown})` : "" }}</el-button>
        </div>
      </template> -->
    </el-dialog>
  </div>
</template>

<script setup>
defineOptions({ name: 'fileEdit' })
import { ref, onMounted, onBeforeUnmount, onActivated, onDeactivated, nextTick } from 'vue';
import jodit from './jodit.vue';
import TopBox from "@/components/TopTitleBox/index.vue";
import FilterSearch from "@/components/TopTitleBox/FilterSearch.vue";
import topButtonGroup from "@/components/ButtonGroup/topButtonGroup.vue";
import topButtonGroupDoc from "@/components/ButtonGroup/topButtonGroupDoc.vue";
import { getDocumentSectionList, getDocumentOutline, getDocumentSection, deleteDocumentOutline, addDocumentOutline, updateDocumentOutline } from '@/api/document';
import { useRoute, onBeforeRouteLeave } from "vue-router";
import { ElMessage, ElMessageBox } from "element-plus";
import router from "@/router";
import useTagStore from '@/stores/tagList'
import { deepClone, removeNodeInTree, getNanoid } from "@/utils/index";
import { moveNodes, collectIds, removeNodes, addNodeToTree, findNodeById } from "./index.js";
const route = useRoute();
const tagStore = useTagStore();
// 侧栏宽度拖动
const leftWidth = ref(20); // 初始宽度设置为 50%
let isDragging = ref(false);
let startX = ref(0);
let startWidth = ref(0);
// 侧栏宽度拖动

const fileName = ref('');
const tabsActiveName = ref('version');
const currentNode = ref({});
const htmlStructure = ref('<p> </p>');
const isCatalogShow = ref(true);
const showMenu = ref(false);
const isExpand = ref(true);
const rendering = ref(true);
const fileDetailsDialog = ref(false);
const treeRef = ref(null);
const scrollContainer = ref(null);
const lastScrollTop = ref(0);
const menuInputRef = ref(null);
const menuStyle = ref({ left: '0px', top: '0px' })
const treeData = ref([])
const treeDataMap = ref(new Map())
const defaultProps = {
  children: 'children',
  label: 'title',
}

const tbuttonList = ref([
  {
    label: "回退",
    icon: "el-icon-back",
    type: "b2",
    onClick: () => {
      console.log("点击了回退");
      tagStore.historyBack({
        name: route.path,
        breadcrumbName: route.params.folderName || "文档",
      });
    },
  },
  {
    label: "前进",
    icon: "el-icon-right",
    type: "b2",
    onClick: () => {
      console.log("点击了我的文件夹");
      tagStore.historyFoward({
        name: `/document/l/myfolder`,
        breadcrumbName: "文档",
      });
    },
  },
  {
    label: "刷新",
    icon: "el-icon-refresh",
    type: "b2",
    onClick: (e) => {
      console.log("点击了刷新");
      loading(e, () => {
        return new Promise((resolve) => {
          setTimeout(() => {
            resolve();
          }, 1000);
        });
      });
    },
  },
  {
    label: "评论",
    icon: "el-icon-ChatDotRound",
    type: "b2",
    onClick: () => {
      console.log("点击了评论");
      fileDetailsDialog.value = true
      tabsActiveName.value = 'comment';
    },
  },
  {
    label: "审批",
    icon: "el-icon-stamp",
    type: "b2",
    onClick: () => {
      console.log("点击了审批");
    },
  },
]);

const onExpand = () => {
  isExpand.value = !isExpand.value
  if (isExpand.value) {
    // 全部展开
    Object.values(treeRef.value?.store?.nodesMap).forEach((v) => v.expand())
  } else {
    // 全部折叠
    Object.values(treeRef.value?.store?.nodesMap).forEach((v) => v.collapse())
  }
}
// 禁用右键处理函数
function handleRightClick(event) {
  event.preventDefault();
}
// 点击树节点
function handleNodeClick(node, TreeNode, eve1, eve2) {
  console.log({ node, TreeNode, eve1, eve2 }, '点击了树节点')
  const joditEditor = document.getElementById('jodit_editor');
  const element = joditEditor.querySelector(`#${CSS.escape(node.id)}`);

  // const element = joditEditor.querySelector(node.id);
  // console.log(element, 'element')
  if (!element) return
  scrollToElementIfNotInView(element);
}
// 节点滚动到视口
const scrollToElementIfNotInView = (element) => {
  // console.log('节点滚动到视口', element);

  const parent = element.parentNode;
  const parentRect = parent.getBoundingClientRect();
  const elementRect = element.getBoundingClientRect();

  // 判断元素是否在可视区域内
  const isInView =
    elementRect.top >= parentRect.top &&
    elementRect.bottom <= parentRect.bottom;

  // 如果元素不在可视区域内，则滚动
  if (!isInView) {
    const scrollTop = element.offsetTop - parent.offsetTop - 50;
    parent.scrollTo({
      top: scrollTop,
      behavior: "smooth",
    });
  }
};
const startDrag = (e) => {
  isDragging.value = true;
  startX.value = e.clientX;
  startWidth.value = leftWidth.value;
  document.addEventListener('mousemove', onDrag);
  document.addEventListener('mouseup', stopDrag);
};
const onDrag = (e) => {
  if (!isDragging.value) return;
  const diff = e.clientX - startX.value;
  let newWidth = startWidth.value + (diff / window.innerWidth) * 100; // 计算宽度变化的百分比
  // 限制最小和最大宽度为 20% 和 40%
  newWidth = Math.min(Math.max(newWidth, 20), 40);
  leftWidth.value = newWidth;
};
const stopDrag = () => {
  isDragging.value = false;
  document.removeEventListener('mousemove', onDrag);
  document.removeEventListener('mouseup', stopDrag);
};
// 大纲树tree 右键事件
function treeHandleRightClick(event, row) {
  console.log("treeHandleRightClick", event, row);
  showContextMenu(event, row);
}
function showContextMenu(event, node) {
  showMenu.value = true;
  menuStyle.value.left = `${event.clientX + 5}px`;
  menuStyle.value.top = `${event.clientY + 5}px`;

  nextTick(() => {
    const contextMenu = document.querySelector('.context_menu');
    if (contextMenu) {
      const contextMenuRect = contextMenu.getBoundingClientRect();
      const viewportHeight = window.innerHeight;
      // 判断context_menu是否在可视区域内
      console.log('判断context_menu是否在可视区域内', contextMenuRect.bottom, viewportHeight);
      if (contextMenuRect.bottom + contextMenuRect.height > viewportHeight) {
        menuStyle.value.transform = `translateY(-${contextMenuRect.height}px)`;
      } else {
        menuStyle.value.transform = `translateY(0)`;
      }
    }
  });
  menuInputRef.value.focus();
  // 保存当前节点数据
  currentNode.value = node;

}


// 搜索回调
const searchCallBack = (word, time) => {
  console.log("搜索回调", word, time);
};
const handleBlur = (event) => {
  console.log('触发handleBlur');

  if (showMenu.value) {
    setTimeout(() => {
      showMenu.value = false;
    }, 500);
  }
}
const handleFocus = (event) => {
  // console.log(event, 'handleFocus');
}

const catalogShow = () => {
  isCatalogShow.value = !isCatalogShow.value;
  console.log('catalogShow展开收起');
}

// 右键添加修改大纲
const updataOutline = (type, isTop = false) => {
  ElMessageBox.prompt("请输入大纲标题", "", {
    confirmButtonText: "确定",
    cancelButtonText: "取消",
    inputValue: type !== 'add' ? currentNode.value.title : '',
    inputPattern: /\S/,
    inputErrorMessage: "大纲标题不能为空",
  })
    .then(({ value }) => {
      console.log("大纲标题", value);

      // ElMessage.success("重命名成功!");
      
      let { id, children = [], level = 0, parentId, sectionOrder, levelCombine, title } = currentNode.value

      console.log(currentNode.value, '右键添加修改大纲');

      let params = {
        "id": 'A' + getNanoid(32),
        "documentId": route.query.id,
        "parentId": id,
        "jsonData": "整个大纲的json数据",
        "sectionOrder": sectionOrder, // 当前层级下 第几个
        "levelCombine": levelCombine, // 完整的level层级
        "level": level + 1, // 层级
        "title": value,
        "content": "<div class='para'><br></div>"
      }
      if (type === 'add') {
        let newId = ''; // 添加章节使用 的id
        let newChildren = deepClone(children);
        console.log(newChildren, 'newChildrennewChildren');

        if (newChildren && newChildren.length) {
          newId = newChildren[newChildren.length - 1].id;
        } else {
          newId = id || ''
        }

        if (isTop) {
          console.log('添加顶层节点');
          params.parentId = '0'
          params.level = 1;
          params.sectionOrder = treeData.value.length + 1;
          params.levelCombine = params.sectionOrder + '';
        } else {
          params.sectionOrder = children.length + 1;
          params.levelCombine = levelCombine + '-' + params.sectionOrder;
        }

        let addNodeData = {
          "children": [],
          "id": params.id,
          "level": params.level,
          "parentId": params.parentId,
          "sectionOrder": params.sectionOrder,
          "levelCombine": params.levelCombine,
          "title": params.title
        }
        if (isTop) {
          treeData.value.push(addNodeData)         
          treeDataMap.value.set(params.id, addNodeData);
        } else {
          addNodeToTree(treeData.value, id, addNodeData)
          treeDataMap.value.set(id, addNodeData);
        }
        params.jsonData = JSON.stringify(treeData.value);
        console.log(params, 'paramsparamsparams', treeData.value);

        // 生成随机id 放入更新后的json 填入title 请求接口
        addDocumentOutline(params).then(res => {
          console.log(res, 'resresres');
          if (res.code == 200) {
            ElMessage.success("添加成功!");
            console.log(newId, 'newIdnewIdnewId');
            let htmlString = `<div class="section" id="${params.id}"><h${params.level} class="title_disable">${params.title}</h${params.level}><div class="child"><div class='para'><br></div></div></div>`
            insertAfter(htmlString, newId)
            nextTick(() => {
              const joditEditor = document.getElementById('jodit_editor');
              const element = joditEditor.querySelector(`#${CSS.escape(params.id)}`);
              // console.log(element, 'element')
              if (!element) return
              scrollToElementIfNotInView(element);
            })
          }
        })
      } else {
        // 重命名
        currentNode.value.title = value;
        params.jsonData = JSON.stringify(treeData.value);
        params.parentId = parentId;
        params.sectionOrder = sectionOrder;
        params.level = level;
        params.id = id;
        delete params.content;

        let treeDataMapItem = treeDataMap.value.get(params.id);
        if(treeDataMapItem){
          treeDataMapItem.title = value;
          treeDataMap.value.set(params.id, treeDataMapItem);
        }
        updateDocumentOutline(params).then(res => {
          if (res.code == 200) {
            ElMessage.success("修改成功!");
            const targetEl = document.getElementById(id);
            if (targetEl) {
              targetEl.querySelector('.title_disable').innerHTML = value;
            }
          }
        })
        
        console.log('更新结果', treeData.value);

      }
      currentNode.value = {};
    })
    .catch((err) => {
      console.log("取消||报错", err);
      currentNode.value = {};
    });
}

function insertAfter(htmlString, targetId) {
  let targetEl = document.getElementById(targetId);
  if (!targetEl || !targetId) {
    console.error(`未找到 id 为 ${targetId} 的元素`);
    // targetEl = document.querySelector('.jodit-workplace > .jodit-wysiwyg');
    const workplace = document.querySelector('.jodit-workplace > .jodit-wysiwyg');
    const directChildren = workplace.children;
    targetEl = directChildren[directChildren.length - 1];
    console.log("找到了", targetEl);
    // targetEl = targetEl.querySelector('.jodit-wysiwyg');
    // return;
  }

  // 创建一个临时容器解析 HTML
  const template = document.createElement("template");
  template.innerHTML = htmlString.trim();
  const newElement = template.content.firstElementChild;

  // 使用 insertAdjacentElement 插入到目标元素之后
  targetEl.insertAdjacentElement("afterend", newElement);
}


// 右键删除大纲
const deleteOutline = () => {
  let treeDataCopy = deepClone(treeData.value);
  removeNodeInTree(treeDataCopy, currentNode.value.id)
  console.log(currentNode.value, '右键删除大纲', treeDataCopy);
  let data = {
    "documentId": route.query.id,
    "jsonData": JSON.stringify(treeDataCopy),
    "ids": [
      currentNode.value.id,
    ]
  }
  deleteDocumentOutline(data).then(res => {
    if (res.code == 200) {
      ElMessage.success("删除成功!");
      removeNodeInTree(treeData.value, currentNode.value.id);
      treeDataMap.value.delete('currentNode.value.id');
      const parentEl = document.querySelector('.jodit-wysiwyg');
      if (parentEl) {
        removeNodes(parentEl, collectIds(currentNode.value));
        currentNode.value = {}
      }
    }
  });
}

// 拖拽时判定目标节点能否成为拖动目标位置
// 'prev'、'inner'、'next'
// 目标节点前、插入至目标节点、放置在目标节点后
const allowDrop = (draggingNode, dropNode, type) => {
  // console.log('拖拽时判定目标节点能否成为拖动目标位置', draggingNode, dropNode, type);
  if (draggingNode.data.parentId === dropNode.data.parentId && type !== 'inner') {
    return true
  } else {
    return false
  }
}

// 判断节点能否被拖拽 如果返回 false ，节点不能被拖动
const allowDrag = (draggingNode) => {
  // console.log('allowDrag节点能不能被拖动', draggingNode);
  return true
}

// 拖拽成功完成时触发的事件
// 被拖拽节点对应的 Node、结束拖拽时最后进入的节点、被拖拽节点的放置位置（before、after、inner）、event
const nodeDrop = (node, dropNode, type, event) => {
  const parentEl = document.querySelector('.jodit-wysiwyg');
  if (parentEl) {
    console.log('拖拽成功完成时触发的事件', node, dropNode, type, event,  parentEl);
    if (type === 'after') {
      let ids = collectIds(dropNode.data)
      moveNodes(parentEl, collectIds(node.data), ids[ids.length - 1], type)
    } else {
      moveNodes(parentEl, collectIds(node.data), dropNode.data.id, type)
    }
  }

}

function onMountedFun() {
  let { id, name } = route.query;
  console.log("onMountedFun", id);
  useTagStore().tagListCopy = deepClone(useTagStore().tagList);
  // 页面禁用右键事件
  document.addEventListener('contextmenu', handleRightClick);
  getDocumentSection(id).then((res) => {
    fileName.value = name;
    if (res.code !== 200 || !res.data) return;
    console.log(res, '获取章节数据');
    htmlStructure.value = res.data || '';
  })
  getDocumentOutline(id).then((res) => {
    if (res.code !== 200) return;
    // console.log(res, '获取大纲数据');
    if (!res.data) return;
    let data = res.data;
    let list = [];
    if (data?.outlineJson && data?.outlineJson !== '[]') {
      list = data?.outlineJson ? JSON.parse(data?.outlineJson) : [];
      console.log(list, '获取大纲数据');
      treeData.value = list;
      buildTreeMap(list)
    }
  })
  getDocumentSectionList({ id: id }).then((res) => {
    if (res.code !== 200) return;
    console.log('获取文章章节列表', res.rows);
  })
}
function buildTreeMap(nodes, parentMap = treeDataMap.value) {
  nodes.forEach(node => {
    // 将当前节点存入 Map
    parentMap.set(node.id, node);
    // 如果有子节点，递归处理
    if (node.children && node.children.length > 0 && node.level <= 2) {
      buildTreeMap(node.children, parentMap);
    }
  });
}
onMounted(async () => {
  console.log('✅ 组件创建', useTagStore().tagList);
  onMountedFun();
});
onBeforeUnmount(() => {
  console.log('组件卸载', 'jodit');
  // 移除事件监听，避免内存泄漏
  document.removeEventListener('contextmenu', handleRightClick);

})
onActivated(() => {
  console.log('✅ 组件被激活', useTagStore().tagList, useTagStore().tagListCopy);
  if (useTagStore().tagListCopy.every(item => item.fullPath !== route.fullPath)) {
    console.log('✅ 组件需要被重置');
    // useTagStore().tagListCopy = deepClone(useTagStore().tagList);
    rendering.value = false;
    setTimeout(() => {
      console.log('✅ 组件被重置');
      rendering.value = true;
      onMountedFun();
    }, 10);
  }
  if (lastScrollTop.value) {
    nextTick(() => {
      const parentEl = document.querySelector('.jodit-wysiwyg');
      if (parentEl) {
        parentEl.scrollTop = lastScrollTop.value;
      }
    })
  }
});

onDeactivated(() => {
  console.log('⏳ 组件被缓存');
  document.removeEventListener('contextmenu', handleRightClick);
});
onBeforeRouteLeave(() => {
  const parentEl = document.querySelector('.jodit-wysiwyg');
  if (parentEl) {
    console.log('⏳ 组件被缓存', parentEl, parentEl.scrollTop);
    lastScrollTop.value = parentEl.scrollTop;
  }
});

</script>

<style lang="scss">
.file_edit {
  position: relative;
  padding: 30px 15px 0;
  height: 100%;
  .topBox .page_title {
    font-weight: bold;
  }
  #jodit_copy {
    display: none;
    width: 78%;
    height: 2.08333rem;
    overflow-y: auto;
    background: #fce8ff;
    overflow-x: hidden;
    position: absolute;
    top: 14%;
    right: 1%;
    padding: 20px;
    border-radius: 10px;
    box-shadow: #6c6c6c 0.00521rem 0.00521rem 0.05208rem 0.00521rem;
  }
  .divider {
    cursor: ew-resize;
    background-color: #ffffff;
    width: 5px;
    height: 100%;
  }
  .menuInput {
    opacity: 0;
    position: absolute;
    top: 0;
    left: 0;
  }
  .context_menu {
    position: fixed;
    background: white;
    box-shadow: 0 2px 10px rgba(0, 0, 0, 0.1);
    z-index: 1000;
    padding: 0 0;
    border-radius: 6px;
    min-width: 155px;
    color: #6c7078;
    overflow: hidden;
    font-size: 14px;
    ul {
      list-style: none;
      padding: 0;
      margin: 0;
    }
    li {
      padding: 4px 23px;
      cursor: pointer;
      // border-bottom: 1px #f0f0f0 solid;
    }
    li:hover {
      background: #f0f0f0;
    }
    li:last-child {
      border: none; // 去掉最后一个li的底部边框
    }
  }
}
.file_edit_cotent {
  display: flex;
  margin-top: 5px;
  height: calc(100% - 50px);
  .tree_box {
    // flex: 1;
    width: 20%;
    // overflow: auto;
    position: relative;
    height: 100%;
    .but_box {
      position: absolute;
      right: 15px;
      top: 0;
      z-index: 1;
    }
    .el-tree {
      height: 100%;
      overflow: auto;
      width: 100%;
      .el-tree-node {
        display: table;
        min-width: 100%;
      }
    }
  }
  .el-tree-node__content {
    position: relative;
  }
  .custom-tree-node {
    flex: 1;
    display: flex;
    align-items: center;
    justify-content: space-between;
    font-size: 14px;
    padding-right: 8px;
    ._contextmenu {
      position: absolute;
      width: 100%;
      height: 100%;
      left: 0;
    }
  }
}
.file_details_dialog > .el-overlay-dialog {
  // right: 5px;
  // left: auto;
  > .el-dialog {
    height: 84%;
    position: absolute;
    right: 18px;
    bottom: 25px;
  }
  ._line {
    border-bottom: 1px solid #ebeef5;
    width: 100%;
  }
  .details {
    padding-bottom: 20px;
    h2 {
      padding: 6px 0;
      font-size: 16px;
      font-weight: bold;
    }
  }
}
</style>